/*****************************************************************************
 * Copyright (C) Stacy Curl. All rights reserved.                            *
 * ------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the BSD      *
 * style license a copy of which has been included with this distribution in *
 * the LICENSE.txt file.                                                     *
 *****************************************************************************/
package picounit.features.verify;

import picounit.features.verify.constraint.StringCaseModifier;
import picounit.verify.BooleanArrayConstraints;
import picounit.verify.BooleanConstraints;
import picounit.verify.ByteArrayConstraints;
import picounit.verify.ByteConstraints;
import picounit.verify.CharacterArrayConstraints;
import picounit.verify.CharacterConstraints;
import picounit.verify.CollectionConstraints;
import picounit.verify.DoubleArrayConstraints;
import picounit.verify.DoubleConstraints;
import picounit.verify.ExtendedStringConstraints;
import picounit.verify.FileConstraints;
import picounit.verify.FloatArrayConstraints;
import picounit.verify.FloatConstraints;
import picounit.verify.IntegerArrayConstraints;
import picounit.verify.IntegerConstraints;
import picounit.verify.ListConstraints;
import picounit.verify.LongArrayConstraints;
import picounit.verify.LongConstraints;
import picounit.verify.SetConstraints;
import picounit.verify.ShortArrayConstraints;
import picounit.verify.ShortConstraints;
import picounit.verify.StringArrayConstraints;
import picounit.verify.StringConstraints;
import picounit.verify.StringConstraintsCaseConsiderationKnown;
import picounit.verify.TypedArrayConstraints;
import picounit.verify.TypedConstraints;

import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.Set;

public class DefaultStringConstraints extends ExtensibleStringConstraints
	implements ExtendedStringConstraints {

	private final Evaluator evaluator;

	private final BooleanConstraints booleanConstraints;
	private final ByteConstraints byteConstraints;
	private final CharacterConstraints charConstraints;
	private final DoubleConstraints doubleConstraints;
	private final FloatConstraints floatConstraints;
	private final IntegerConstraints intConstraints;
	private final LongConstraints longConstraints;
	private final ShortConstraints shortConstraints;
	private final FileConstraints fileConstraints;
	private final TypedConstraints typedConstraints;
	private final BooleanArrayConstraints booleanArrayConstraints;
	private final ByteArrayConstraints byteArrayConstraints;
	private final CharacterArrayConstraints characterArrayConstraints;
	private final DoubleArrayConstraints doubleArrayConstraints;
	private final FloatArrayConstraints floatArrayConstraints;
	private final IntegerArrayConstraints integerArrayConstraints;
	private final LongArrayConstraints longArrayConstraints;
	private final ShortArrayConstraints shortArrayConstraints;
	private final StringArrayConstraints stringArrayConstraints;
	private final TypedArrayConstraints typedArrayConstraints;
	private final CollectionConstraints collectionConstraints;
	private final ListConstraints listConstraints;
	private final SetConstraints setConstraints;

	public DefaultStringConstraints(Evaluator evaluator, BooleanConstraints booleanConstraints,
		ByteConstraints byteConstraints, CharacterConstraints charConstraints,
		DoubleConstraints doubleConstraints, FloatConstraints floatConstraints,
		IntegerConstraints intConstraints, LongConstraints longConstraints,
		ShortConstraints shortConstraints, FileConstraints fileConstraints,
		TypedConstraints typedConstraints, BooleanArrayConstraints booleanArrayConstraints,
		ByteArrayConstraints byteArrayConstraints,
		CharacterArrayConstraints characterArrayConstraints,
		DoubleArrayConstraints doubleArrayConstraints, FloatArrayConstraints floatArrayConstraints,
		IntegerArrayConstraints integerArrayConstraints, LongArrayConstraints longArrayConstraints,
		ShortArrayConstraints shortArrayConstraints, StringArrayConstraints stringArrayConstraints,
		TypedArrayConstraints typedArrayConstraints, CollectionConstraints collectionConstraints,
		ListConstraints listConstraints, SetConstraints setConstraints) {

		super(evaluator);

		this.evaluator = evaluator;
		
		this.booleanConstraints = booleanConstraints;
		this.byteConstraints = byteConstraints;
		this.charConstraints = charConstraints;
		this.doubleConstraints = doubleConstraints;
		this.floatConstraints = floatConstraints;
		this.intConstraints = intConstraints;
		this.longConstraints = longConstraints;
		this.shortConstraints = shortConstraints;
		this.fileConstraints = fileConstraints;
		this.typedConstraints = typedConstraints;
		this.booleanArrayConstraints = booleanArrayConstraints;
		this.byteArrayConstraints = byteArrayConstraints;
		this.characterArrayConstraints = characterArrayConstraints;
		this.doubleArrayConstraints = doubleArrayConstraints;
		this.floatArrayConstraints = floatArrayConstraints;
		this.integerArrayConstraints = integerArrayConstraints;
		this.longArrayConstraints = longArrayConstraints;
		this.shortArrayConstraints = shortArrayConstraints;
		this.stringArrayConstraints = stringArrayConstraints;
		this.typedArrayConstraints = typedArrayConstraints;
		this.collectionConstraints = collectionConstraints;
		this.listConstraints = listConstraints;
		this.setConstraints = setConstraints;
	}

	public StringConstraintsCaseConsiderationKnown ignoringCase() {
		setModifier(StringCaseModifier.INSTANCE);

		return this;
	}

	///////////////////////////////////////////////////////////////////////////////////////////////
	// ValueCapturer Methods
	///////////////////////////////////////////////////////////////////////////////////////////////

	public BooleanConstraints byChecking(boolean value) {
		setValue(value);

		return booleanConstraints;
	}

	public ByteConstraints byChecking(byte value) {
		setValue(value);

		return byteConstraints;
	}

	public CharacterConstraints byChecking(char value) {
		setValue(value);

		return charConstraints;
	}

	public DoubleConstraints byChecking(double value) {
		setValue(value);

		return doubleConstraints;
	}

	public FloatConstraints byChecking(float value) {
		setValue(value);

		return floatConstraints;
	}

	public IntegerConstraints byChecking(int value) {
		setValue(value);

		return intConstraints;
	}

	public LongConstraints byChecking(long value) {
		setValue(value);

		return longConstraints;
	}

	public ShortConstraints byChecking(short value) {
		setValue(value);

		return shortConstraints;
	}

	public FileConstraints byChecking(File value) {
		setValue(value);

		return fileConstraints;
	}

	public StringConstraints byChecking(String value) {
		setValue(value);

		return this;
	}

	@SuppressWarnings("unchecked")
	public <T> TypedConstraints<T> byChecking(T value) {
		setValue(value);

		return typedConstraints;
	}

	public BooleanArrayConstraints byChecking(boolean... value) {
		setValue(value);

		return booleanArrayConstraints;
	}

	public ByteArrayConstraints byChecking(byte... value) {
		setValue(value);

		return byteArrayConstraints;
	}

	public CharacterArrayConstraints byChecking(char... value) {
		setValue(value);

		return characterArrayConstraints;
	}

	public DoubleArrayConstraints byChecking(double... value) {
		setValue(value);

		return doubleArrayConstraints;
	}

	public FloatArrayConstraints byChecking(float... value) {
		setValue(value);

		return floatArrayConstraints;
	}

	public IntegerArrayConstraints byChecking(int... value) {
		setValue(value);

		return integerArrayConstraints;
	}

	public LongArrayConstraints byChecking(long... value) {
		setValue(value);

		return longArrayConstraints;
	}

	public ShortArrayConstraints byChecking(short... value) {
		setValue(value);

		return shortArrayConstraints;
	}

	public StringArrayConstraints byChecking(String... value) {
		setValue(value);

		return stringArrayConstraints;
	}

	@SuppressWarnings("unchecked")
	public <T> TypedArrayConstraints<T> byChecking(T... value) {
		setValue(value);

		return typedArrayConstraints;
	}

	@SuppressWarnings("unchecked")
	public <T> CollectionConstraints<T> byChecking(Collection<T> value) {
		setValue(value);

		return collectionConstraints;
	}

	@SuppressWarnings("unchecked")
	public <T> ListConstraints<T> byChecking(List<T> value) {
		setValue(value);

		return listConstraints;
	}

	@SuppressWarnings("unchecked")
	public <T> SetConstraints<T> byChecking(Set<T> value) {
		setValue(value);

		return setConstraints;
	}

	///////////////////////////////////////////////////////////////////////////////////////////////
	// Implementation
	///////////////////////////////////////////////////////////////////////////////////////////////

	private void setValue(Object object) {
		// Should interpret the value set in verify.that(value) as denoting the reason
		evaluator.setReason((String) evaluator.getValue());

		evaluator.setValue(object);
	}
}
